package com.boarsoft.rpc.http.jetty.connector;

import java.net.SocketAddress;
import java.net.URL;

import org.eclipse.jetty.http3.api.Session;
import org.eclipse.jetty.http3.server.HTTP3ServerConnector;
import org.eclipse.jetty.http3.server.RawHTTP3ServerConnectionFactory;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.boarsoft.rpc.RpcConfig;

/**
 * HTTP 2 connector
 * 
 * @author Mac_J
 *
 */
public class Http3ConnectorBuilder implements ConnectorBuilder {
	private static final Logger log = LoggerFactory.getLogger(Http3ConnectorBuilder.class);
	/** */
	protected int port = 8443;
	/** */
	protected String host = "localhost";
	/** */
	protected long idleTimeout = 3000000;
	/** */
	protected HttpConfiguration config;
	/** */
	protected String ksPassword = "boar-rpc";
	/** */
	protected String kmPassword = "boar-rpc";
	/** */
	protected String sslKeystore = "/com/boarsoft/rpc/http/jetty/key/server.jks";
	/** */
	protected String keystorePath = RpcConfig.getString("ssl.keystore.path", sslKeystore);
	/** The listener for session events. */
	protected Session.Server.Listener sessionListener = new Session.Server.Listener() {
		@Override
		public void onAccept(Session session) {
			SocketAddress remoteAddress = session.getRemoteSocketAddress();
			log.info("Connection from {}", remoteAddress);
		}
	};

	@Override
	public Connector build(Server server) {
		// HTTP/3 is always secure, so it always need a SslContextFactory.
		SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
		sslContextFactory.setKeyStorePath(sslKeystore);
		sslContextFactory.setKeyStorePassword(keystorePath);
		// URL keyURL = Http3ConnectorBuilder.class.getResource(keystorePath);
		// sslContextFactory.setKeyStoreResource(Resource.newResource(keyURL));
		sslContextFactory.setKeyStorePassword(ksPassword);
		sslContextFactory.setKeyManagerPassword(kmPassword);

		// Create and configure the RawHTTP3ServerConnectionFactory.
		RawHTTP3ServerConnectionFactory http3 = new RawHTTP3ServerConnectionFactory(sessionListener);
		http3.getHTTP3Configuration().setStreamIdleTimeout(15000);

		// Create and configure the HTTP3ServerConnector.
		HTTP3ServerConnector connector = new HTTP3ServerConnector(server, sslContextFactory, http3);
		// Configure the max number of requests per QUIC connection.
		connector.getQuicConfiguration().setMaxBidirectionalRemoteStreams(1024);

		connector.setHost(host);
		connector.setPort(port);
		connector.setIdleTimeout(idleTimeout);
		return connector;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public long getIdleTimeout() {
		return idleTimeout;
	}

	public void setIdleTimeout(long idleTimeout) {
		this.idleTimeout = idleTimeout;
	}

	public HttpConfiguration getConfig() {
		return config;
	}

	public void setConfig(HttpConfiguration config) {
		this.config = config;
	}

	public String getKsPassword() {
		return ksPassword;
	}

	public void setKsPassword(String ksPassword) {
		this.ksPassword = ksPassword;
	}

	public String getKmPassword() {
		return kmPassword;
	}

	public void setKmPassword(String kmPassword) {
		this.kmPassword = kmPassword;
	}
}
